package com.code.generate;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.mozilla.intl.chardet.nsDetector;
import org.mozilla.intl.chardet.nsICharsetDetectionObserver;
import org.mozilla.intl.chardet.nsPSMDetector;

public class FileOperator {

	/**
	 * @Fields p : 模式为"@{****}"的字符串都被定义为变量
	 */
	private static Pattern p = Pattern.compile("@\\{([A-Z]|[a-z]|[^\\x00-\\xff])+\\}");
	private static Pattern all = Pattern.compile("@\\{([A-Z]|[a-z]|[^\\x00-\\xff]|_)+\\}");
	private static String fileCharset = null;

	/**
	 * 读取文件内容
	 * 
	 * @param file
	 * @return
	 */
	public static String readFile(MyFile file) {
		StringBuffer sb = new StringBuffer();
		try {
			System.out.println("file.path : " + file.getPath());
			InputStreamReader read = new InputStreamReader(new FileInputStream(file), FileOperator.getEncode(file));
			BufferedReader br = new BufferedReader(read);
			while (br.ready()) {
				String line = br.readLine();
				sb = sb.append(line).append("\n");
			}
			br.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return sb.toString().trim();
	}

	/**
	 * 获取文件的编码格式
	 * 
	 * @param file
	 * @return
	 */
	public static synchronized String getEncode(File file) {
		fileCharset = null;
		try {
			nsDetector det = new nsDetector(nsPSMDetector.CHINESE);
			det.Init(new nsICharsetDetectionObserver() {
				@Override
				public void Notify(String charset) {
					fileCharset = charset;
				}
			});
			BufferedInputStream imp = new BufferedInputStream(new FileInputStream(file));
			byte[] buf = new byte[1024];
			int len;
			boolean done = false;
			boolean isAscii = true;
			while ((len = imp.read(buf, 0, buf.length)) != -1) {
				if (isAscii)
					isAscii = det.isAscii(buf, len);
				if (!isAscii && !done)
					done = det.DoIt(buf, len, false);
			}
			det.DataEnd();
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (fileCharset == null) {
			fileCharset = "UTF-8";
		}

		return fileCharset;
	}

	/**
	 * 获取所有文件的列表，如果是文件夹，则采用递归的方式获取
	 * 
	 * @param f
	 * @return
	 */
	public static List<MyFile> getAllFile(File f) {
		List<MyFile> allFileList = new ArrayList<MyFile>();
		if (!f.getName().contains(".svn")) {
			if (f.isFile()) {
				allFileList.add(new MyFile(f));
			} else {
				// 如果是文件夹，则需要继续获取
				for (File file : f.listFiles()) {
					allFileList.addAll(getAllFile(file));
				}
			}
		}
		return allFileList;
	}

	/**
	 * 获取参数信息
	 * 
	 * @param str
	 * @param ifAll
	 * @return
	 */
	public static Set<String> getVariables(String str, boolean ifAll) {
		Set<String> variables = new HashSet<String>();
		Matcher m = null;
		if (ifAll)
			m = all.matcher(str);
		else
			m = p.matcher(str);
		while (m.find()) {
			variables.add(m.group());
		}
		return variables;
	}

	/**
	 * 
	 * 获取所有的变更参数信息
	 * 
	 * @param f
	 * @return
	 */
	public static Set<String> getAllVariables(MyFile f) {
		Set<String> variables = new HashSet<String>();

		// 先获取所有的文件
		List<MyFile> files = FileOperator.getAllFile(f);
		for (MyFile mf : files) {
			variables.addAll(getVariables(readFile(mf), true));
		}

		// if (f.isFile()) {
		// variables.addAll(getVariables(readFile(f), false));
		// } else {
		// for (File temp : f.listFiles()) {
		// variables.addAll(getAllVariables(new MyFile(temp)));
		// }
		// }
		// variables.addAll(getVariables(f.getAbsolutePath(), false));
		return variables;
	}

	public static void main(String[] args) {
		// Set<String> de =
		// getVariables("abeta @{测试} is@{th——is} @{my_waz},today()");
		// for (String s : de) {
		// System.out.println(s);
		// }

		String filePath = "F:/work/code/kepler/code-generate/CodeTemplate/标准模板/gmcc-management-project/gmcc-management-web/src/main/webapp/@{子系统名称}/@{模块名称_FIRST_LOWER}/index.jsp";

		// String encode = getEncode(new File(filePath));

		MyFile mf = new MyFile(new File(filePath));

		Set<String> variables = FileOperator.getAllVariables(mf);
		for (String variable : variables) {
			System.out.println(variable);
		}

		System.out.println();
	}
}
